home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 201-225 / disk_203 / examples / audiodev / audio.doc < prev    next >
Text File  |  1992-05-06  |  7KB  |  98 lines

  1.   This is a direct replacement for KickStart's audio device. This replacement
  2. is both smaller and faster than Commodore's official release. When KickStart
  3. is booted, the audio.device is loaded into an area (of the Amiga 1000) which
  4. is thereafter write-protected. It is not possible to overwrite, or delete
  5. the functions of the device (aside from creating a custom KickStart disc). On
  6. the Amiga 2000 and 500, KickStart is already in system ROM and no part of
  7. it (including the audio device) can be altered.
  8.   Exec automatically creates the device's function table and Base structure
  9. during the boot procedure, and links its node into the list of devices
  10. thereby making its existance "known" to the system. Unfortunately, the
  11. replacement device cannot be opened as "audio.device" while the original
  12. exists (even if the version number is different). We could call the device
  13. something besides "audio.device", but then applications would have to be
  14. rewritten to open this new device explicitly. By finding some way of fooling
  15. Exec into thinking that the replacement is the original, all applications
  16. will be directed to this replacement automatically. Calling the function
  17. RemLibrary to remove the original would seem to be the answer. For some
  18. bizarre reason, Exec's OpenDevice "knows" that the audio device's functions
  19. can be found in the protected memory even after the original is removed from
  20. Exec's list of devices. The result is that instead of looking for the
  21. (replacement) device in the devs drawer of the bootdisk (as it should),
  22. Exec always creates a function table for the original functions in the pro-
  23. tected memory. Net result, you can't get rid of the fucker using the standard
  24. (i.e. the official, documented) procedure.
  25.   We need to open the original device, and replace each one of its vectors
  26. in the function table (Open, Close, Expunge, BeginIO, and AbortIO) with the
  27. replacement's vectors (via SetFunction). Furthermore, we need to replace the
  28. assembly language "audio block done" handlers as they are also tighter than
  29. the originals. Finally, we must not allow this new device to be expunged
  30. (i.e. removed when no more tasks have it open). If another task tried to
  31. open the audio device after it had been expunged, Exec would construct the
  32. original device all over again. Stupid? Of course! Many of the lame-brained
  33. bugs in the Amiga operating system are due to the fact that too many C
  34. programmers were allowed to write the operating system. Aside from the speed
  35. penalties of not using assembly language, much of the operating system was
  36. compiled with the Amiga C compiler which had a fatal bug as demonstated in
  37. the following code. This code was extracted directly from the version 33.4
  38. audio device which is what is on KickStart 1.2.
  39.  
  40. .1 move.l  a2,-(a7)
  41.    bsr.s   someFunction
  42.    clr.b   $1e(a2)
  43. .2 tst.b   $1f(a2) ;test some value for 0
  44. .3 addq.l  #8,a7   ;Oooppps! Someone didn't realize that this affects the Z flag
  45. .4 beq.s   .5      ;Uh oh. We aren't branching as a result of the test at .2
  46.  
  47.   At label .1, the contents of register a2 are pushed onto the stack. This
  48. is how C code passes values between functions. A call is made to someFunction.
  49. Now, when returning from someFunction, the stack needs to be re-adjusted
  50. because of that previous push. The Amiga C Compiler always adjusts for the
  51. stack only before a branch needs to be taken, or before an rts. In this way,
  52. the stack can be readjusted for several calls in one instruction instead of
  53. after each individual call. This is perfectly good if the adjustment is made
  54. using the lea instruction {as in lea  12(a7),a7}. Unfortunately, whoever
  55. wrote the C compiler also used the addq instruction to make adjustments to
  56. the stack. This instruction affects ALL the status register flags. Note that
  57. this instruction is sandwiched inbetween the tst instruction and the beq.
  58. Obviously, the stack isn't ever going to be zero when we add 8 to it. Conse-
  59. quently, the branch on equal to .5 WILL NEVER BE TAKEN. Since a large part
  60. of the amiga operating system is written in C (particularly Intuition) and
  61. compiled with this compiler, and this original code is still part of the
  62. 1.2 operating system, one can understand why mysterious GURU crashes still
  63. occur. Don't necessarily blame the application software.
  64.   Also, the audio device's Expunge routine seems to be completely illogical.
  65. Exec is only allowed to Expunge when the device's OpenCnt (# of tasks which
  66. have it open) is NOT 0! If you open the device and call RemLibrary, Exec
  67. will indeed remove it from under your nose. Imagine that a task has the
  68. audio device open, the amount of free memory is low, and some task makes an
  69. allocation request for a block larger than currently available. Exec will
  70. snake through its list of devices, calling the Expunge routine of each in an
  71. attempt to remove those that are no longer being used. A device's Expunge
  72. routine is supposed to fail (i.e. return 0) if the device is being used, but
  73. in this case, Exec is allowed to remove the audio device and use its memory.
  74. Now what happens when that poor task who thinks that he has the audio device
  75. open tries to call a device function that may have been overwritten? BANG!!!
  76. Something ugly is probably going to happen though its anyone's guess exactly
  77. what. By the way, the audio device's (version 33.4) Expunge routine is
  78. written in C.
  79.   I undertook to rewrite the device in assembly for 2 reasons:
  80. 1). A realtime function (i.e. audio output) should be written in the most
  81.     efficient language available. (That's assembly, not C).
  82. 2). Someone had to correct the bugs in the C code.
  83.   In order to replace the original device after KickStart is loaded, I wrote
  84. a program called NewAudio. Since this program needs to be executed only
  85. once, a good place to execute it is in the startup-sequence (probably last
  86. after all the dust has settled). This program installs the new functions and
  87. handlers, and assures that the device cannot be expunged under any circumstances.
  88. This results in approximately 3K being dedicated to a permanent audio
  89. device. I think that this is worth having a faster device (most all programs
  90. that feature sound use the audio device instead of manipulating the hardware
  91. directly), and one that won't cause a possible system crash.
  92.   Alternately, after booting the computer, you can double click on the
  93. NewAudio icon. Just be sure that you do this as soon as Workbench comes up
  94. (i.e. before you run any program that uses the audio device). You need only
  95. do this once.
  96.  
  97.    JEFF GLATT     dissidents
  98.